package com.ksyun.campus.dataserver.controller;

import com.ksyun.campus.dataserver.domain.StatInfo;
import com.ksyun.campus.dataserver.dto.WriteReqDto;
import com.ksyun.campus.dataserver.dto.req.DataServerFixReqDto;
import com.ksyun.campus.dataserver.dto.req.ReadReqDto;
import com.ksyun.campus.dataserver.dto.resp.DataServerAllFilesRespDto;
import com.ksyun.campus.dataserver.dto.resp.ReadRespDto;
import com.ksyun.campus.dataserver.response.BaseResult;
import com.ksyun.campus.dataserver.services.DataService;
import org.springframework.beans.factory.annotation.Value;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.web.bind.annotation.*;

@Slf4j
@RestController
@RequestMapping("/data")
public class DataController {

    @Value("${storagePath}")
    private String STORAGE_PATH;

    @Autowired
    private DataService dataService;

    @Autowired
    private ApplicationContext applicationContext;

    @PostMapping("/write")
    public BaseResult<StatInfo> writeFile(
//            @RequestHeader(value = "fileSystemName", required = true) String fileSystemName,
            @RequestHeader String fileSystemName,
            @RequestBody WriteReqDto writeReqDto) {

        log.debug("Received fileSystemName: {}", fileSystemName);
        log.debug("Received WriteReqDto: {}", writeReqDto);

        try {
            StatInfo result = dataService.write(fileSystemName, writeReqDto.getStatInfo(), writeReqDto.getFileBytes());
            return BaseResult.success(result);
        } catch (Exception e) {
            log.error("Error writing file", e);
            throw e; // 让 GlobalExceptionHandler 处理
        }
    }

    @PostMapping("/read")
    public BaseResult<ReadRespDto> readFile(
            @RequestHeader String fileSystemName,
            @RequestBody ReadReqDto readReqDto) {

        String path = readReqDto.getPath();
        int offset = readReqDto.getOffset();
        int length = readReqDto.getLength();
        StatInfo statInfo = readReqDto.getStatInfo();

        try {
            ReadRespDto result = dataService.read(fileSystemName, path, offset, length, statInfo);
            return BaseResult.success(result);
        } catch (Exception e) {
            log.error("Error reading file", e);
            throw e; // 让 GlobalExceptionHandler 处理
        }
    }

    @PostMapping("/delete")
    public BaseResult<StatInfo> deleteFile(
            @RequestHeader String fileSystemName,
            @RequestBody WriteReqDto writeReqDto) {

        try {
            boolean deleted = dataService.delete(fileSystemName, writeReqDto.getStatInfo());
            if (deleted) {
                return BaseResult.success(writeReqDto.getStatInfo());
            } else {
                return BaseResult.error("删除文件失败");
            }
        } catch (Exception e) {
            log.error("Error deleting file", e);
            throw e; // 让 GlobalExceptionHandler 处理
        }
    }

    @GetMapping("/getAllFiles")
    public BaseResult<DataServerAllFilesRespDto> getAllFiles(){
        DataServerAllFilesRespDto dataServiceAllFiles=dataService.getAllFiles();
        return BaseResult.success(dataServiceAllFiles);
    }

    /**
     * 获取当前节点保存文件的路径
     *
     * @return 当前节点的存储路径
     */
    @GetMapping("/getStoragePath")
    public String getStoragePath() {
        return dataService.getStoragePath();
    }

    //    fixFiles, post请求，文件头fileSystemName+请求体DataServerFixReqDto
    @PostMapping("/fixFiles")
    public BaseResult<Boolean> fixFiles(
            @RequestHeader String fileSystemName,
            @RequestBody DataServerFixReqDto dataServerFixReqDto) {

        Boolean bool=dataService.fixFiles(fileSystemName, dataServerFixReqDto);
        return BaseResult.success(bool);
    }

    @PostMapping("/shutdown")
    public void shutdownServer() {
        log.info("收到关闭服务实例请求");

        new Thread(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            ((ConfigurableApplicationContext) applicationContext).close();
            log.info("正在关闭服务实例...");
        }).start();
    }
}
